package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private VodService vodService;

	@Autowired
	private TrackStatMapper trackStatMapper;

	@Autowired
	private UserFeignClient userFeignClient;

	/**
	 *  保存专辑
	 * @param trackInfoVo
	 * @param userId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {

		TrackInfo trackInfo = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);

		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());

		trackInfo.setUserId(userId);
		trackInfo.setOrderNum(albumInfo.getIncludeTrackCount() + 1);
		trackInfo.setSource("1");
		trackInfo.setStatus("0501");

		TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
		if (trackMediaInfoVo != null) {
			trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
			trackInfo.setMediaSize(trackMediaInfoVo.getSize());
			trackInfo.setMediaType(trackMediaInfoVo.getType());
		}

		//1.5 保存声音得到声音ID
		trackInfoMapper.insert(trackInfo);
		Long trackId = trackInfo.getId();

		//2.新增声音统计信息
		this.saveTrackStat(trackId, SystemConstant.TRACK_STAT_PLAY, 0);
		this.saveTrackStat(trackId, SystemConstant.TRACK_STAT_COLLECT, 0);
		this.saveTrackStat(trackId, SystemConstant.TRACK_STAT_PRAISE, 0);
		this.saveTrackStat(trackId, SystemConstant.TRACK_STAT_COMMENT, 0);

		//3.更新专辑包含声音数量
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount()+1);
		albumInfoMapper.updateById(albumInfo);
	}

	@Override
	public Page<TrackListVo> findUserTrackPage(Page<TrackListVo> trackListVoPage,TrackInfoQuery trackInfoQuery) {
		return albumInfoMapper.selectTrackPage(trackListVoPage,trackInfoQuery);
	}

	@Override
	public void updateTrackInfo(Long id,TrackInfoVo trackInfoVo) {

		// 根据id查询旧声音
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		// 获取旧声音云点播唯一标识
		String before = trackInfo.getMediaFileId();
		// 获取新声音唯一标识
		String after = trackInfoVo.getMediaFileId();

		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		if(!before.equals(after)){
			TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(after);
			if(trackMediaInfo!=null){
				trackInfo.setMediaType(trackMediaInfo.getType());
				trackInfo.setMediaDuration(BigDecimal.valueOf(trackMediaInfo.getDuration()));
				trackInfo.setMediaSize(trackMediaInfo.getSize());
				//4.将变更前声音文件从云点播平台删除
				vodService.deleteTrackMedia(before);
			}
		}
		trackInfoMapper.updateById(trackInfo);
	}

	/**
	 * 新增专辑统计信息
	 * @param trackId 声音ID
	 * @param statType 统计类型
	 * @param statNum 统计数值
	 */
	public void saveTrackStat(Long trackId, String statType, int statNum) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(trackId);
		trackStat.setStatType(statType);
		trackStat.setStatNum(statNum);
		trackStatMapper.insert(trackStat);
	}

	/**
	 *  track_info，album_info，track_stat，media
	 * @param id
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeTrackInfo(Long id) {
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		trackInfoMapper.deleteById(trackInfo);

		Integer orderNum = trackInfo.getOrderNum();

		// 更新排序
		trackInfoMapper.updateOrderNum(trackInfo.getAlbumId(),orderNum);

		// 删除声音统计记录
		QueryWrapper<TrackStat> trackStatQueryWrapper = new QueryWrapper<>();
		trackStatQueryWrapper.eq("track_id",id);
		trackStatMapper.delete(trackStatQueryWrapper);

		// 更新专辑数量
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() - 1);
		albumInfoMapper.updateById(albumInfo);

		// 删除云点播声音
		vodService.deleteTrackMedia(trackInfo.getMediaFileId());
	}

	@Override
	public TrackStatVo getTrackStatVo(Long trackId) {
		return trackStatMapper.getTrackStatVo(trackId);
	}


	@Override
	public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount) {
		// 查询当前声音
		TrackInfo trackInfo = this.getById(trackId);

		// 查询用户已经购买的声音
		List<Long> userPaidTrackList = userFeignClient.findUserPaidTrackList(trackInfo.getAlbumId()).getData();
		log.info("查询用户已经购买的声音:{}",userPaidTrackList);

		//3.根据专辑ID+当前声音序号查询大于当前声音待购买声音列表
		LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(TrackInfo::getAlbumId,trackInfo.getAlbumId());
		wrapper.ge(TrackInfo::getOrderNum,trackInfo.getOrderNum());
		if(CollectionUtil.isNotEmpty(userPaidTrackList)){
			wrapper.notIn(TrackInfo::getId,userPaidTrackList);
		}
		wrapper.last("limit " + trackCount);
		wrapper.select(TrackInfo::getId, TrackInfo::getTrackTitle, TrackInfo::getCoverUrl, TrackInfo::getAlbumId);
		//3.4 对声音进行排序：按照序号升序
		wrapper.orderByAsc(TrackInfo::getOrderNum);
		// 查询
		List<TrackInfo> trackInfoList = this.list(wrapper);
		if (CollectionUtil.isEmpty(trackInfoList)) {
			throw new GuiguException(400, "该专辑下没有符合购买要求声音");
		}
		return trackInfoList;

	}

	@Override
	public List<Map<String, Object>> findUserTrackPaidList(Long trackId) {
		// 根据声音id查询声音
		TrackInfo trackInfo = trackInfoMapper.selectById(trackId); // 本集声音
		Assert.notNull(trackInfo,"查询声音错误,声音ID:{}",trackInfo);
		// 根据声音的orderNum查询之后的所有声音
		LambdaQueryWrapper<TrackInfo> trackInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
		trackInfoLambdaQueryWrapper.eq(TrackInfo::getAlbumId,trackInfo.getAlbumId());
		trackInfoLambdaQueryWrapper.ge(TrackInfo::getOrderNum,trackInfo.getOrderNum());

		List<TrackInfo> waitForBuy = this.list(trackInfoLambdaQueryWrapper);

		// 查询用户已经购买的声音,过滤掉已经购买过的
		List<Long> userPaidTrackIdList = userFeignClient.findUserPaidTrackList(trackInfo.getAlbumId()).getData();

		// 过滤已经购买的
		if(CollectionUtil.isNotEmpty(userPaidTrackIdList)){
			waitForBuy = waitForBuy.stream().filter(userBought -> {
				return !userPaidTrackIdList.contains(userBought.getId());
			}).collect(Collectors.toList());
		}

		//5.基于实际购买声音列表长度，动态构建分集购买对象
		List<Map<String, Object>> mapList = new ArrayList<>();
		if(CollectionUtil.isEmpty(waitForBuy)){
			throw new GuiguException(400,"您已全部购买，无需再次购买");
		}
		//5.1 根据专辑ID查询专辑得到单集价格
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		BigDecimal price = albumInfo.getPrice();
		//5.1 构建本集购买对象
		Map<String, Object> currMap = new HashMap<>();
		currMap.put("name", "本集");
		currMap.put("price", price);
		currMap.put("trackCount", 1);
		mapList.add(currMap);
		//5.2 判断待购买声音数量 数量<10 动态展示后count集合 价格=count*price 数量=count
		int count = waitForBuy.size();
		for (int i = 10; i <= 50; i += 10) {
			//判断数量>i 固定显示后i集
			if (count > i) {
				Map<String, Object> map = new HashMap<>();
				map.put("name", "后" + i + "集");
				map.put("price", price.multiply(new BigDecimal(i)));
				map.put("trackCount", i);
				mapList.add(map);
			} else {
				//反之全集（动态构建后count集合）
				Map<String, Object> map = new HashMap<>();
				map.put("name", "后" + count + "集");
				map.put("price", price.multiply(new BigDecimal(count)));
				map.put("trackCount", count);
				mapList.add(map);
				break;
			}
		}
		return mapList;
	}

	@Override
	public Page<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> albumTrackListVoPage, Long albumId,Long userId) {

		// 查询声音列表
		Page<AlbumTrackListVo> albumTrackPage = trackInfoMapper.findAlbumTrackPage(albumTrackListVoPage, albumId);

		//  用户为空的时候，然后找出哪些是需要付费的声音并显示付费 isShowPaidMark=true
		//	付费类型： 0101-免费 0102-vip免费 0103-付费

		// 查询专辑的pay_type
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		Assert.notNull(albumInfo,"专辑不存在,专辑id:{}",albumId);

		if(userId == null){
			// 如果是 VIP免费 和 付费的情况， 前tracks_for_free集的 isShowPaidMark = true
			if (albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE)
					|| albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)){

				albumTrackPage.getRecords().stream()
						.forEach(albumTrackListVo -> {
					albumTrackListVo.setIsShowPaidMark(albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree());
				});

			}
		}else {
//			-获取用户信息 判断用户的类型
			UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
			Assert.notNull(userInfoVo, "用户{}不存在", userId);
			Integer isVip = userInfoVo.getIsVip();

			//4.2 默认设置需要进一步确定购买情况标识：默认false
			Boolean isNeedCheckPayStatus = false;

//			- vip 免费类型
			if(SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(albumInfo.getPayType())){
				//	- 如果不是vip  需要付费
				if (isVip == 0) isNeedCheckPayStatus = true;
				//- 如果是vip 但是已经过期了 也需要付费
				if(isVip == 1 && new Date().after(userInfoVo.getVipExpireTime())) isNeedCheckPayStatus = true;

			}
			// vip 付费类型
			if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())){
				isNeedCheckPayStatus = true;
			}

			//- 统一处理需要付费业务
			if(isNeedCheckPayStatus){
				// 把除了免费试听集数过滤出来，然后查用户是否购买,购买了的就设置 false,否者都为 true

				List<AlbumTrackListVo> afterTracksForFree = albumTrackPage.getRecords().stream().filter(albumTrackListVo -> {
					return albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree();
				}).collect(Collectors.toList());

				List<Long> afterTracksForFreeId = afterTracksForFree.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());

				Map<Long, Integer> map = userFeignClient.userIsPaidTrack(userId, albumId, afterTracksForFreeId).getData();

				Assert.notNull(map, "userFeignClient.userIsPaidTrack 调用失败 userId:{},albumId:{},afterTracksForFreeId{}", userId,albumId,afterTracksForFreeId);

				afterTracksForFree.forEach(albumTrackListVo -> {

					Integer payStatus = map.get(albumTrackListVo.getTrackId());
					if (payStatus.intValue() == 0) {
						//4.5 某个声音用户未购买，将设置付费标识 isShowPaidMark:true
						albumTrackListVo.setIsShowPaidMark(true);
					}
				});
			}
		}

		return albumTrackPage;
	}
}








































